package com.example.hook_activity.hookUtil;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherActivityInfo;
import android.os.Message;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

import android.os.Handler;


import androidx.annotation.NonNull;

public class HookUtil9 {
    private Context context;
    private Class<?> activity;
    public HookUtil9(Context context, Class<?> activity) {
        this.context = context;
        this.activity = activity;
    }
    public void hookAT(){
        try {
            Class activityTreadClazz = Class.forName("android.app.ActivityThread");
            Field sCurrentActivityThreadField = activityTreadClazz.getDeclaredField("sCurrentActivityThread");
            sCurrentActivityThreadField.setAccessible(true);
            Object sCurrentActivityThreadObj = sCurrentActivityThreadField.get(null);

            Field mHField = activityTreadClazz.getDeclaredField("mH");
            mHField.setAccessible(true);
            Handler handlerObj = (Handler) mHField.get(sCurrentActivityThreadObj);//从sCurrentActivityThreadObj实例获取mh的实例

            Field mCallbackField = Handler.class.getDeclaredField("mCallback");
            mCallbackField.setAccessible(true);
            ProxyHandlerCallBack proxyHandlerCallBack = new ProxyHandlerCallBack();
            mCallbackField.set(handlerObj,proxyHandlerCallBack);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    class ProxyHandlerCallBack implements Handler.Callback{

        @Override
        public boolean handleMessage(@NonNull Message msg) {
            Log.e("message",""+msg.what);
            //activityThread中mh的定义在app跳转时
            if (msg.what ==159){
                Log.e("message",""+msg.obj.getClass().toString());
                try {
                    //在activityThread中执行159步骤所用类为ClientTransaction，为抽象类，子类为LaunchActivityItem
                    Class clientTransactionClazz = Class.forName("android.app.servertransaction.ClientTransaction");
                    if (!clientTransactionClazz.isInstance(msg.obj)) return true;
                    //取出其中的mActivityCallbacks变量，因为所需的LaunchActivityItem变量存放在该列表中，LaunchActivityItem携带所需intent
                    Class launchActivityItemClazz = Class.forName("android.app.servertransaction.LaunchActivityItem");
                    Field mActivityCallsField = clientTransactionClazz.getDeclaredField("mActivityCallbacks");
                    mActivityCallsField.setAccessible(true);
                    Object mActivityCallbacksObj = mActivityCallsField.get(msg.obj);

                    List mActivityCallbacksList  = (List) mActivityCallbacksObj;
                    if (mActivityCallbacksList.size() == 0)return true;
                    //取出LaunchActivityItem对象并做类型判断
                    Object launchActivityItemObj = ((List) mActivityCallbacksObj).get(0);
                    if (!launchActivityItemClazz.isInstance(launchActivityItemObj))return true;
                    //取出intent
                    Field mIntentField = launchActivityItemClazz.getDeclaredField("mIntent");
                    mIntentField.setAccessible(true);

                    Intent mIntent = (Intent) mIntentField.get(launchActivityItemObj);
                    Intent realIntent = mIntent.getParcelableExtra("oldIntent");
                    if (realIntent != null){
                        mIntent.setComponent(realIntent.getComponent());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
    }
    public void hookAms(){
        try {
            Class clazz = Class.forName("android.app.ActivityTaskManager"); //获取方法
            Field IActivityManagerSingleton = clazz.getDeclaredField("IActivityTaskManagerSingleton");//field类似变量  object类似对象实例
            IActivityManagerSingleton.setAccessible(true);
            Object IActivityManagerSingletonOBJ = IActivityManagerSingleton.get(null); //获取源对象
            Class clazz1 = Class.forName("android.util.Singleton"); //获取singleton对象
            Field mInstance = clazz1.getDeclaredField("mInstance"); //获取IActivityManagerSingleton中的mInstance，即IActivityManager
            mInstance.setAccessible(true);
            //在debug时发现mInstance对象是存在的，但是不能直接调用mInstance.get方法，暂时没有Android10的源码，应该是ActivityTaskManager中做了某些修改(个人猜测)
//            Object IActivityManager = mInstance.get(IActivityManagerSingletonOBJ);
            //android10中ActivityTaskManager的singleton对象中的mInstance不能直接取出，需要主动执行get方法
            Object IActivityManager = clazz1.getDeclaredMethod("get").invoke(IActivityManagerSingletonOBJ);
//            Log.e("IActivityManager: ", IActivityManager.toString());

            //IActivityManagerSingletonOBJ内有proxy和stub接口，此处用动态代理实现自定义功能
            Class IActivityManagerClz = Class.forName("android.app.IActivityTaskManager");
            Object proxyIActivityManager =  Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{IActivityManagerClz},new AmsInvocationHandler(IActivityManager));
            //将IActivityManagerSingleton中的mInstance的接口替换
            mInstance.setAccessible(true);
            //本次hook点为IActivityManagerSingleton中的mInstance对象,，该句的意思为为IActivityManagerSingletonOBJ(对象)中的mInstance(成员，变量)赋值(proxyIActivityManager)
            mInstance.set(IActivityManagerSingletonOBJ,proxyIActivityManager);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    class AmsInvocationHandler implements InvocationHandler{
        private Object IActivityManager;
        public AmsInvocationHandler( Object IActivityManager) {
            this.IActivityManager = IActivityManager;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Log.e("执行我的方法", method.getName());
            if("startActivity".contains(method.getName())){
                Log.e("startActivity", "执行我的方法");
                Intent intent = null;
                int i = 0;
                for(int n = 0; n < args.length; n++){
                    Object arg = args[n];
                    if (arg instanceof Intent){
                        i = n;
                        intent = (Intent) arg;
                        break;
                    }
                }
                Intent proxyIntent = new Intent();
                ComponentName componentName = new ComponentName(context,activity);
                proxyIntent.setComponent(componentName);
                //隐藏原意图
                proxyIntent.putExtra("oldIntent", intent);
                args[i] = proxyIntent;

            }
            return   method.invoke(IActivityManager,args);
        }
    }

}
